import json
from io import BytesIO

from minio.error import S3Error
from seaman.core import JsonUtil, Validator

from common.method import *
from common.test import get_test_base_data


class Completion:
    # 类变量 未处理方法
    _list_: List[CompletionData]



    def __init__(self, _list_: [BaseData]):


        # 获取数据
        self._list_ = _list_
        # 获取长度
        list_size = len(_list_)
        t_list: List[CompletionData] = []
        # 判断第一个点深度
        first_record: BaseData = _list_[0]
        # 不为 0 补全 --> 大部分条件下应该是全的，属于是两层保险
        if first_record.depth != 0.0:
            t: CompletionData = CompletionData(first_record)
            t.depth = 0.0
            t.azimuth = 0.0
            t.inclination = 0.0
            t.north = 0
            t.east = 0
            t.true_vertical_depth = 0
            t_list.append(t)
        for idx in range(0, list_size):
            t: CompletionData = CompletionData(_list_[idx])
            t_list.append(t)
            # 强制深度 0 开始
            # if idx == 0:
            #     t.north = 0
            #     t.east = 0
            #     t.true_vertical_depth = 0
            # t_list.append(t)
        self._list_ = t_list

    # X 偏移量计算
    # a 为需要填充的数据 Data_i b为已知数据 Data_(i-1)
    def get_delta_north(a: CompletionData, b: CompletionData) -> float:
        # print('计算系数为:',get_delta_factor(a, b))
        return get_delta_factor(a, b) * (math.sin(math.radians(b.inclination)) * math.cos(math.radians(b.azimuth)) +
                                         math.sin(math.radians(a.inclination)) * math.cos(math.radians(a.azimuth)))

    # X 计算
    # a 为需要填充的数据 N_i b为已知数据 N_(i-1)
    def get_north(a: CompletionData, b: CompletionData) -> float:
        # 偏移 north 计算
        delta_north: float = Completion.get_delta_north(a, b)
        # print('深度增量', a.depth, delta_north)
        # 最终结果
        north: float = b.north + delta_north
        # 返回
        return north

    # Y 偏移量计算
    def get_delta_east(a: CompletionData, b: CompletionData) -> float:
        return get_delta_factor(a, b) * (math.sin(math.radians(a.inclination)) * math.sin(math.radians(a.azimuth)) +
                                         math.sin(math.radians(b.inclination)) * math.sin(math.radians(b.azimuth)))

    # Y 计算
    def get_east(a: CompletionData, b: CompletionData) -> float:
        # 偏移 east 计算
        delta_east: float = Completion.get_delta_east(a, b)
        # 最终结果
        east: float = b.east + delta_east
        # 返回
        return east

    def get_delta_true_vertical_depth(a: CompletionData, b: CompletionData) -> float:
        return get_delta_factor(a, b) * (math.cos(math.radians(a.inclination)) + math.cos(math.radians(b.inclination)))

    # Z 坐标计算
    def get_true_vertical_depth(a: CompletionData, b: CompletionData) -> float:
        # 偏移 tvd 计算
        delta_true_vertical_depth: float = Completion.get_delta_true_vertical_depth(a, b)
        # 最终结果
        true_vertical_depth = delta_true_vertical_depth + b.true_vertical_depth
        # 返回
        return true_vertical_depth



    # 执行
    def run(self) -> List[CompletionData]:
        return Completion.execute(self)

    def execute(self) -> List[CompletionData]:
        _list_: [CompletionData] = self._list_
        data_size = len(_list_)
        for idx in range(1, data_size):

            _list_[idx].north = Completion.get_north(_list_[idx], _list_[idx - 1])
            _list_[idx].east = Completion.get_east(_list_[idx], _list_[idx - 1])
            _list_[idx].true_vertical_depth = Completion.get_true_vertical_depth(_list_[idx], _list_[idx - 1])
            # print(JsonUtil.obj2str(oil_data_list[idx]))
        for idx in range(0, data_size):
            _list_[idx].north = round(_list_[idx].north, 2)
            _list_[idx].east = round(_list_[idx].east, 2)
            _list_[idx].true_vertical_depth = round(_list_[idx].true_vertical_depth, 2)
        # 数据写入
        self._list_ = _list_
        return _list_

    def export(self, _path_: str):
        _list_: List[CompletionData] = self._list_
        data = [
            {
                '井深': o.depth,
                '井斜角': o.inclination,
                '方位角': o.azimuth,
                'x': o.north,
                'y': o.east,
                'z': o.true_vertical_depth,
                '全角': o.full_angle
            }
            for o in _list_
        ]
        df = pd.DataFrame(data)
        return None
#
#
# if __name__ == '__main__':
#     data_list: List[BaseData] = get_test_base_data()
#     completion = Completion(data_list)
#     _list_: List[CompletionData] = completion.execute()
#     for item in _list_:
#         print(JsonUtil.obj2str(item))
